package scene.shape.materials;
import raytracing.HitRecord;
import scene.Scene;
import scene.lighting.Light;
import scene.shape.geometry.Triangle;
import util.Color3f;
import util.Vector3f;


/**
 * A class representing a Lambertian material
 * @author glenn
 *
 */
public class Material {
	
	public static final float AMBIENT_COEFF = 0.2f;
	public static final float DIFFUSE_COEFF = 0.7f;
	public static final float ATTENUATION = 0.99f;
	
	public static final int MAX_RECURSIONDEPTH = 3;
	
	protected Color3f color;
	protected String name;
	
	public Material(Color3f color, String name){
		this.color = color;
		this.name = name;
	}
	
	public String getName(){
		return name;
	}
	
	public Color3f getColor(){
		return color;
	}
	
	public Color3f shade(HitRecord hr, Light light, int recursiondepth){
		if(recursiondepth > MAX_RECURSIONDEPTH)
			return new Color3f(0,0,0);
		Vector3f l = light.getPosition().subtract(hr.getIntersectionPoint()).normalize();
		return getDiffuseShading(hr.getNormal(),l,light);
	}
	
	public Color3f shade(HitRecord hr, int recursiondepth){
		if(recursiondepth > MAX_RECURSIONDEPTH)
			return new Color3f(0,0,0);
		return getAmbientShading();
	}
	
	public Color3f shade(Triangle t, float alpha, float beta, float gamma){
		Color3f c = getAmbientShading();
		Vector3f n = t.getWeightedNormal(alpha, beta, gamma).normalize();
		for(Light light : Scene.getInstance().getLights()){
			Vector3f l = light.getPosition().subtract(t.getPointAt(alpha, beta, gamma)).normalize();
			c = c.add(getDiffuseShading(n,l,light));
		}
		return c;
	}
	
	public Color3f getAmbientShading(){
		return color.scale(AMBIENT_COEFF);
	}
	
	public Color3f getDiffuseShading(Vector3f n, Vector3f l, Light light){
		float dot = Math.max(0,n.dot(l)) * DIFFUSE_COEFF * ATTENUATION * light.getIntensity();//max(0,n.l)
		float ir = light.getColor().x * color.x * dot,
			  ig = light.getColor().y * color.y * dot,
			  ib = light.getColor().z * color.z * dot;
		return new Color3f(ir,ig,ib);
	}
	
	public Color3f getDiffuseShading(HitRecord hr){
		Color3f c = new Color3f(0,0,0);
		Vector3f n = hr.getNormal();
		for(Light light : Scene.getInstance().getLights()){
			Vector3f l = light.getPosition().subtract(hr.getIntersectionPoint()).normalize();
			c = c.add(getDiffuseShading(n, l, light));
		}
		return c;
	}
	
	public boolean isLightingDependent(){
		return true;
	}

	public boolean isShadowable() {
		return true;
	}

}
